package com.lz.gmall.rabbit.service.Impl;

import com.lz.gmall.rabbit.service.RabbitBizService;
import com.rabbitmq.client.Channel;
import lombok.extern.slf4j.Slf4j;
import org.bouncycastle.crypto.digests.MD5Digest;
import org.springframework.amqp.core.Message;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.DigestUtils;

import java.io.IOException;

/**
 * @author 郭运龙
 * 设置重试次数，rabbitmq失败重试的次数
 * 提取出来，可以公用
 */
@Service
@Slf4j
public class RabbitBizServiceImpl implements RabbitBizService {

    @Autowired
    private RedisTemplate<String,String> redisTemplate;

    /**
     *
     * @param msg  发送的消息
     * @param message  存放消息的对象
     * @param channel 信道
     * @param num   重试次数
     */
    @Override
    public void retryer(String msg, Message message, Channel channel, Long num) {
        //采用md5加密的方式
        String md5DigestAsHex = DigestUtils.md5DigestAsHex(message.getBody());
        Long increment = redisTemplate.opsForValue().increment("msg:count:" + md5DigestAsHex);
        if (increment>num){
            //TODO：把消息加入数据库，后期采用人工补偿

            //TODO： 把消息实际消费次数从Redis中删除掉
            redisTemplate.delete("msg:count:" + md5DigestAsHex);
            try {
                //超过重试次数，不再重试，返回ack，从死信队列中删除
                channel.basicAck(message.getMessageProperties().getDeliveryTag(),true);
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }else {
            //还没达到重试次数，接着重试
            try {
                log.info("出现异常重试了一次");
                channel.basicNack(message.getMessageProperties().getDeliveryTag(),true,true);
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
    }
}
